--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
sbapp/pydub/effects.py 9e636de5b17a8d48ccb9f7caff7ba9c0bee2ca44 (9e636de5) Text, 11.51 KB
Tff7b72import T7ee787sys
Tff7b72import T7ee787math
Tff7b72import T7ee787array
Tff7b72from T7ee787.T7ee787utils Tff7b72import Tb4b4b4(
Te6edf3db_to_floatTb4b4b4,
Te6edf3ratio_to_dbTb4b4b4,
Te6edf3register_pydub_effectTb4b4b4,
Te6edf3make_chunksTb4b4b4,
Te6edf3audioopTb4b4b4,
Te6edf3get_min_max_value
Tb4b4b4)
Tff7b72from T7ee787.T7ee787silence Tff7b72import Te6edf3split_on_silence
Tff7b72from T7ee787.T7ee787exceptions Tff7b72import Te6edf3TooManyMissingFramesTb4b4b4, Te6edf3InvalidDuration
Tff7b72if Te6edf3sysTff7b72.Td2a8ffversion_info Tff7b72>Tff7b72= Tb4b4b4(T79c0ff3Tb4b4b4, T79c0ff0Tb4b4b4)Tb4b4b4:
Te6edf3xrange Tff7b72= Tffa657range
Tf0883e@register_pydub_effect
Tff7b72def Td2a8ffapply_mono_filter_to_each_channelTb4b4b4(Te6edf3segTb4b4b4, Te6edf3filter_fnTb4b4b4)Tb4b4b4:
Te6edf3n_channels Tff7b72= Te6edf3segTff7b72.Td2a8ffchannels
Te6edf3channel_segs Tff7b72= Te6edf3segTff7b72.Td2a8ffsplit_to_monoTb4b4b4(Tb4b4b4)
Te6edf3channel_segs Tff7b72= Tb4b4b4[Te6edf3filter_fnTb4b4b4(Te6edf3channel_segTb4b4b4) Tff7b72for Te6edf3channel_seg Tff7b72in Te6edf3channel_segsTb4b4b4]
Te6edf3out_data Tff7b72= Te6edf3segTff7b72.Td2a8ffget_array_of_samplesTb4b4b4(Tb4b4b4)
Tff7b72for Te6edf3channel_iTb4b4b4, Te6edf3channel_seg Tff7b72in Tffa657enumerateTb4b4b4(Te6edf3channel_segsTb4b4b4)Tb4b4b4:
Tff7b72for Te6edf3sample_iTb4b4b4, Te6edf3sample Tff7b72in Tffa657enumerateTb4b4b4(Te6edf3channel_segTff7b72.Td2a8ffget_array_of_samplesTb4b4b4(Tb4b4b4)Tb4b4b4)Tb4b4b4:
Te6edf3index Tff7b72= Tb4b4b4(Te6edf3sample_i Tff7b72* Te6edf3n_channelsTb4b4b4) Tff7b72+ Te6edf3channel_i
Te6edf3out_dataTb4b4b4[Te6edf3indexTb4b4b4] Tff7b72= Te6edf3sample
Tff7b72return Te6edf3segTff7b72.Td2a8ff_spawnTb4b4b4(Te6edf3out_dataTb4b4b4)
Tf0883e@register_pydub_effect
Tff7b72def Td2a8ffnormalizeTb4b4b4(Te6edf3segTb4b4b4, Te6edf3headroomTff7b72=T79c0ff0.1Tb4b4b4)Tb4b4b4:
T8b949e"""
headroom is how close to the maximum volume to boost the signal up to (specified in dB)
"""
Te6edf3peak_sample_val Tff7b72= Te6edf3segTff7b72.Td2a8ffmax
T8b949e# if the max is 0, this audio segment is silent, and can't be normalized
Tff7b72if Te6edf3peak_sample_val Tff7b72== T79c0ff0Tb4b4b4:
Tff7b72return Te6edf3seg
Te6edf3target_peak Tff7b72= Te6edf3segTff7b72.Td2a8ffmax_possible_amplitude Tff7b72* Te6edf3db_to_floatTb4b4b4(Tff7b72-Te6edf3headroomTb4b4b4)
Te6edf3needed_boost Tff7b72= Te6edf3ratio_to_dbTb4b4b4(Te6edf3target_peak Tff7b72/ Te6edf3peak_sample_valTb4b4b4)
Tff7b72return Te6edf3segTff7b72.Td2a8ffapply_gainTb4b4b4(Te6edf3needed_boostTb4b4b4)
Tf0883e@register_pydub_effect
Tff7b72def Td2a8ffspeedupTb4b4b4(Te6edf3segTb4b4b4, Te6edf3playback_speedTff7b72=T79c0ff1.5Tb4b4b4, Te6edf3chunk_sizeTff7b72=T79c0ff150Tb4b4b4, Te6edf3crossfadeTff7b72=T79c0ff25Tb4b4b4)Tb4b4b4:
T8b949e# we will keep audio in 150ms chunks since one waveform at 20Hz is 50ms long
T8b949e# (20 Hz is the lowest frequency audible to humans)
T8b949e# portion of AUDIO TO KEEP. if playback speed is 1.25 we keep 80% (0.8) and
T8b949e# discard 20% (0.2)
Te6edf3atk Tff7b72= T79c0ff1.0 Tff7b72/ Te6edf3playback_speed
Tff7b72if Te6edf3playback_speed Tff7b72< T79c0ff2.0Tb4b4b4:
T8b949e# throwing out more than half the audio - keep 50ms chunks
Te6edf3ms_to_remove_per_chunk Tff7b72= Tffa657intTb4b4b4(Te6edf3chunk_size Tff7b72* Tb4b4b4(T79c0ff1 Tff7b72- Te6edf3atkTb4b4b4) Tff7b72/ Te6edf3atkTb4b4b4)
Tff7b72elseTb4b4b4:
T8b949e# throwing out less than half the audio - throw out 50ms chunks
Te6edf3ms_to_remove_per_chunk Tff7b72= Tffa657intTb4b4b4(Te6edf3chunk_sizeTb4b4b4)
Te6edf3chunk_size Tff7b72= Tffa657intTb4b4b4(Te6edf3atk Tff7b72* Te6edf3chunk_size Tff7b72/ Tb4b4b4(T79c0ff1 Tff7b72- Te6edf3atkTb4b4b4)Tb4b4b4)
T8b949e# the crossfade cannot be longer than the amount of audio we're removing
Te6edf3crossfade Tff7b72= Tffa657minTb4b4b4(Te6edf3crossfadeTb4b4b4, Te6edf3ms_to_remove_per_chunk Tff7b72- T79c0ff1Tb4b4b4)
T8b949e# DEBUG
T8b949e#print("chunk: {0}, rm: {1}".format(chunk_size, ms_to_remove_per_chunk))
Te6edf3chunks Tff7b72= Te6edf3make_chunksTb4b4b4(Te6edf3segTb4b4b4, Te6edf3chunk_size Tff7b72+ Te6edf3ms_to_remove_per_chunkTb4b4b4)
Tff7b72if Tffa657lenTb4b4b4(Te6edf3chunksTb4b4b4) Tff7b72< T79c0ff2Tb4b4b4:
Tff7b72raise Tf85149ExceptionTb4b4b4(Ta5d6ff"Ta5d6ffCould not speed up AudioSegment, it was too short Tffd700{2:0.2f}Ta5d6ffs for the current settings:Tffea00\nTffd700{0}Ta5d6ffms chunks at Tffd700{1:0.1f}Ta5d6ffx speedupTa5d6ff"Tff7b72.Td2a8ffformatTb4b4b4(
Te6edf3chunk_sizeTb4b4b4, Te6edf3playback_speedTb4b4b4, Te6edf3segTff7b72.Td2a8ffduration_secondsTb4b4b4)Tb4b4b4)
T8b949e# we'll actually truncate a bit less than we calculated to make up for the
T8b949e# crossfade between chunks
Te6edf3ms_to_remove_per_chunk Tff7b72-Tff7b72= Te6edf3crossfade
T8b949e# we don't want to truncate the last chunk since it is not guaranteed to be
T8b949e# the full chunk length
Te6edf3last_chunk Tff7b72= Te6edf3chunksTb4b4b4[Tff7b72-T79c0ff1Tb4b4b4]
Te6edf3chunks Tff7b72= Tb4b4b4[Te6edf3chunkTb4b4b4[Tb4b4b4:Tff7b72-Te6edf3ms_to_remove_per_chunkTb4b4b4] Tff7b72for Te6edf3chunk Tff7b72in Te6edf3chunksTb4b4b4[Tb4b4b4:Tff7b72-T79c0ff1Tb4b4b4]Tb4b4b4]
Te6edf3out Tff7b72= Te6edf3chunksTb4b4b4[T79c0ff0Tb4b4b4]
Tff7b72for Te6edf3chunk Tff7b72in Te6edf3chunksTb4b4b4[T79c0ff1Tb4b4b4:Tb4b4b4]Tb4b4b4:
Te6edf3out Tff7b72= Te6edf3outTff7b72.Td2a8ffappendTb4b4b4(Te6edf3chunkTb4b4b4, Te6edf3crossfadeTff7b72=Te6edf3crossfadeTb4b4b4)
Te6edf3out Tff7b72+Tff7b72= Te6edf3last_chunk
Tff7b72return Te6edf3out
Tf0883e@register_pydub_effect
Tff7b72def Td2a8ffstrip_silenceTb4b4b4(Te6edf3segTb4b4b4, Te6edf3silence_lenTff7b72=T79c0ff1000Tb4b4b4, Te6edf3silence_threshTff7b72=Tff7b72-T79c0ff16Tb4b4b4, Te6edf3paddingTff7b72=T79c0ff100Tb4b4b4)Tb4b4b4:
Tff7b72if Te6edf3padding Tff7b72> Te6edf3silence_lenTb4b4b4:
Tff7b72raise Te6edf3InvalidDurationTb4b4b4(Ta5d6ff"Ta5d6ffpadding cannot be longer than silence_lenTa5d6ff"Tb4b4b4)
Te6edf3chunks Tff7b72= Te6edf3split_on_silenceTb4b4b4(Te6edf3segTb4b4b4, Te6edf3silence_lenTb4b4b4, Te6edf3silence_threshTb4b4b4, Te6edf3paddingTb4b4b4)
Te6edf3crossfade Tff7b72= Te6edf3padding Tff7b72/ T79c0ff2
Tff7b72if Tff7b72not Tffa657lenTb4b4b4(Te6edf3chunksTb4b4b4)Tb4b4b4:
Tff7b72return Te6edf3segTb4b4b4[T79c0ff0Tb4b4b4:T79c0ff0Tb4b4b4]
Te6edf3seg Tff7b72= Te6edf3chunksTb4b4b4[T79c0ff0Tb4b4b4]
Tff7b72for Te6edf3chunk Tff7b72in Te6edf3chunksTb4b4b4[T79c0ff1Tb4b4b4:Tb4b4b4]Tb4b4b4:
Te6edf3seg Tff7b72= Te6edf3segTff7b72.Td2a8ffappendTb4b4b4(Te6edf3chunkTb4b4b4, Te6edf3crossfadeTff7b72=Te6edf3crossfadeTb4b4b4)
Tff7b72return Te6edf3seg
Tf0883e@register_pydub_effect
Tff7b72def Td2a8ffcompress_dynamic_rangeTb4b4b4(Te6edf3segTb4b4b4, Te6edf3thresholdTff7b72=Tff7b72-T79c0ff20.0Tb4b4b4, Te6edf3ratioTff7b72=T79c0ff4.0Tb4b4b4, Te6edf3attackTff7b72=T79c0ff5.0Tb4b4b4, Te6edf3releaseTff7b72=T79c0ff50.0Tb4b4b4)Tb4b4b4:
T8b949e"""
Keyword Arguments:
threshold - default: -20.0
Threshold in dBFS. default of -20.0 means -20dB relative to the
maximum possible volume. 0dBFS is the maximum possible value so
all values for this argument sould be negative.
ratio - default: 4.0
Compression ratio. Audio louder than the threshold will be
reduced to 1/ratio the volume. A ratio of 4.0 is equivalent to
a setting of 4:1 in a pro-audio compressor like the Waves C1.
attack - default: 5.0
Attack in milliseconds. How long it should take for the compressor
to kick in once the audio has exceeded the threshold.
release - default: 50.0
Release in milliseconds. How long it should take for the compressor
to stop compressing after the audio has falled below the threshold.
For an overview of Dynamic Range Compression, and more detailed explanation
of the related terminology, see:
http://en.wikipedia.org/wiki/Dynamic_range_compression
"""
Te6edf3thresh_rms Tff7b72= Te6edf3segTff7b72.Td2a8ffmax_possible_amplitude Tff7b72* Te6edf3db_to_floatTb4b4b4(Te6edf3thresholdTb4b4b4)
Te6edf3look_frames Tff7b72= Tffa657intTb4b4b4(Te6edf3segTff7b72.Td2a8ffframe_countTb4b4b4(Te6edf3msTff7b72=Te6edf3attackTb4b4b4)Tb4b4b4)
Tff7b72def Td2a8ffrms_atTb4b4b4(Te6edf3frame_iTb4b4b4)Tb4b4b4:
Tff7b72return Te6edf3segTff7b72.Td2a8ffget_sample_sliceTb4b4b4(Te6edf3frame_i Tff7b72- Te6edf3look_framesTb4b4b4, Te6edf3frame_iTb4b4b4)Tff7b72.Td2a8ffrms
Tff7b72def Td2a8ffdb_over_thresholdTb4b4b4(Te6edf3rmsTb4b4b4)Tb4b4b4:
Tff7b72if Te6edf3rms Tff7b72== T79c0ff0Tb4b4b4: Tff7b72return T79c0ff0.0
Te6edf3db Tff7b72= Te6edf3ratio_to_dbTb4b4b4(Te6edf3rms Tff7b72/ Te6edf3thresh_rmsTb4b4b4)
Tff7b72return Tffa657maxTb4b4b4(Te6edf3dbTb4b4b4, T79c0ff0Tb4b4b4)
Te6edf3output Tff7b72= Tb4b4b4[Tb4b4b4]
T8b949e# amount to reduce the volume of the audio by (in dB)
Te6edf3attenuation Tff7b72= T79c0ff0.0
Te6edf3attack_frames Tff7b72= Te6edf3segTff7b72.Td2a8ffframe_countTb4b4b4(Te6edf3msTff7b72=Te6edf3attackTb4b4b4)
Te6edf3release_frames Tff7b72= Te6edf3segTff7b72.Td2a8ffframe_countTb4b4b4(Te6edf3msTff7b72=Te6edf3releaseTb4b4b4)
Tff7b72for Te6edf3i Tff7b72in Te6edf3xrangeTb4b4b4(Tffa657intTb4b4b4(Te6edf3segTff7b72.Td2a8ffframe_countTb4b4b4(Tb4b4b4)Tb4b4b4)Tb4b4b4)Tb4b4b4:
Te6edf3rms_now Tff7b72= Te6edf3rms_atTb4b4b4(Te6edf3iTb4b4b4)
T8b949e# with a ratio of 4.0 this means the volume will exceed the threshold by
T8b949e# 1/4 the amount (of dB) that it would otherwise
Te6edf3max_attenuation Tff7b72= Tb4b4b4(T79c0ff1 Tff7b72- Tb4b4b4(T79c0ff1.0 Tff7b72/ Te6edf3ratioTb4b4b4)Tb4b4b4) Tff7b72* Te6edf3db_over_thresholdTb4b4b4(Te6edf3rms_nowTb4b4b4)
Te6edf3attenuation_inc Tff7b72= Te6edf3max_attenuation Tff7b72/ Te6edf3attack_frames
Te6edf3attenuation_dec Tff7b72= Te6edf3max_attenuation Tff7b72/ Te6edf3release_frames
Tff7b72if Te6edf3rms_now Tff7b72> Te6edf3thresh_rms Tff7b72and Te6edf3attenuation Tff7b72<Tff7b72= Te6edf3max_attenuationTb4b4b4:
Te6edf3attenuation Tff7b72+Tff7b72= Te6edf3attenuation_inc
Te6edf3attenuation Tff7b72= Tffa657minTb4b4b4(Te6edf3attenuationTb4b4b4, Te6edf3max_attenuationTb4b4b4)
Tff7b72elseTb4b4b4:
Te6edf3attenuation Tff7b72-Tff7b72= Te6edf3attenuation_dec
Te6edf3attenuation Tff7b72= Tffa657maxTb4b4b4(Te6edf3attenuationTb4b4b4, T79c0ff0Tb4b4b4)
Te6edf3frame Tff7b72= Te6edf3segTff7b72.Td2a8ffget_frameTb4b4b4(Te6edf3iTb4b4b4)
Tff7b72if Te6edf3attenuation Tff7b72!= T79c0ff0.0Tb4b4b4:
Te6edf3frame Tff7b72= Te6edf3audioopTff7b72.Td2a8ffmulTb4b4b4(Te6edf3frameTb4b4b4,
Te6edf3segTff7b72.Td2a8ffsample_widthTb4b4b4,
Te6edf3db_to_floatTb4b4b4(Tff7b72-Te6edf3attenuationTb4b4b4)Tb4b4b4)
Te6edf3outputTff7b72.Td2a8ffappendTb4b4b4(Te6edf3frameTb4b4b4)
Tff7b72return Te6edf3segTff7b72.Td2a8ff_spawnTb4b4b4(Te6edf3dataTff7b72=Ta5d6ffbTa5d6ff'Ta5d6ff'Tff7b72.Td2a8ffjoinTb4b4b4(Te6edf3outputTb4b4b4)Tb4b4b4)
T8b949e# Invert the phase of the signal.
Tf0883e@register_pydub_effect
Tff7b72def Td2a8ffinvert_phaseTb4b4b4(Te6edf3segTb4b4b4, Te6edf3channelsTff7b72=Tb4b4b4(T79c0ff1Tb4b4b4, T79c0ff1Tb4b4b4)Tb4b4b4)Tb4b4b4:
T8b949e"""
channels- specifies which channel (left or right) to reverse the phase of.
Note that mono AudioSegments will become stereo.
"""
Tff7b72if Te6edf3channels Tff7b72== Tb4b4b4(T79c0ff1Tb4b4b4, T79c0ff1Tb4b4b4)Tb4b4b4:
Te6edf3inverted Tff7b72= Te6edf3audioopTff7b72.Td2a8ffmulTb4b4b4(Te6edf3segTff7b72.Td2a8ff_dataTb4b4b4, Te6edf3segTff7b72.Td2a8ffsample_widthTb4b4b4, Tff7b72-T79c0ff1.0Tb4b4b4)
Tff7b72return Te6edf3segTff7b72.Td2a8ff_spawnTb4b4b4(Te6edf3dataTff7b72=Te6edf3invertedTb4b4b4)
Tff7b72elseTb4b4b4:
Tff7b72if Te6edf3segTff7b72.Td2a8ffchannels Tff7b72== T79c0ff2Tb4b4b4:
Te6edf3leftTb4b4b4, Te6edf3right Tff7b72= Te6edf3segTff7b72.Td2a8ffsplit_to_monoTb4b4b4(Tb4b4b4)
Tff7b72elseTb4b4b4:
Tff7b72raise Tf85149ExceptionTb4b4b4(Ta5d6ff"Ta5d6ffCanTa5d6ff'Ta5d6fft implicitly convert an AudioSegment with Ta5d6ff" Tff7b72+ Tffa657strTb4b4b4(Te6edf3segTff7b72.Td2a8ffchannelsTb4b4b4) Tff7b72+ Ta5d6ff"Ta5d6ff channels to stereo.Ta5d6ff"Tb4b4b4)
Tff7b72if Te6edf3channels Tff7b72== Tb4b4b4(T79c0ff1Tb4b4b4, T79c0ff0Tb4b4b4)Tb4b4b4:
Te6edf3left Tff7b72= Te6edf3leftTff7b72.Td2a8ffinvert_phaseTb4b4b4(Tb4b4b4)
Tff7b72elseTb4b4b4:
Te6edf3right Tff7b72= Te6edf3rightTff7b72.Td2a8ffinvert_phaseTb4b4b4(Tb4b4b4)
Tff7b72return Te6edf3segTff7b72.Td2a8fffrom_mono_audiosegmentsTb4b4b4(Te6edf3leftTb4b4b4, Te6edf3rightTb4b4b4)
T8b949e# High and low pass filters based on implementation found on Stack Overflow:
T8b949e# http://stackoverflow.com/questions/13882038/implementing-simple-high-and-low-pass-filters-in-c
Tf0883e@register_pydub_effect
Tff7b72def Td2a8fflow_pass_filterTb4b4b4(Te6edf3segTb4b4b4, Te6edf3cutoffTb4b4b4)Tb4b4b4:
T8b949e"""
cutoff - Frequency (in Hz) where higher frequency signal will begin to
be reduced by 6dB per octave (doubling in frequency) above this point
"""
Te6edf3RC Tff7b72= T79c0ff1.0 Tff7b72/ Tb4b4b4(Te6edf3cutoff Tff7b72* T79c0ff2 Tff7b72* Te6edf3mathTff7b72.Td2a8ffpiTb4b4b4)
Te6edf3dt Tff7b72= T79c0ff1.0 Tff7b72/ Te6edf3segTff7b72.Td2a8ffframe_rate
Te6edf3alpha Tff7b72= Te6edf3dt Tff7b72/ Tb4b4b4(Te6edf3RC Tff7b72+ Te6edf3dtTb4b4b4)
Te6edf3original Tff7b72= Te6edf3segTff7b72.Td2a8ffget_array_of_samplesTb4b4b4(Tb4b4b4)
Te6edf3filteredArray Tff7b72= Te6edf3arrayTff7b72.Td2a8ffarrayTb4b4b4(Te6edf3segTff7b72.Td2a8ffarray_typeTb4b4b4, Te6edf3originalTb4b4b4)
Te6edf3frame_count Tff7b72= Tffa657intTb4b4b4(Te6edf3segTff7b72.Td2a8ffframe_countTb4b4b4(Tb4b4b4)Tb4b4b4)
Te6edf3last_val Tff7b72= Tb4b4b4[T79c0ff0Tb4b4b4] Tff7b72* Te6edf3segTff7b72.Td2a8ffchannels
Tff7b72for Te6edf3i Tff7b72in Tffa657rangeTb4b4b4(Te6edf3segTff7b72.Td2a8ffchannelsTb4b4b4)Tb4b4b4:
Te6edf3last_valTb4b4b4[Te6edf3iTb4b4b4] Tff7b72= Te6edf3filteredArrayTb4b4b4[Te6edf3iTb4b4b4] Tff7b72= Te6edf3originalTb4b4b4[Te6edf3iTb4b4b4]
Tff7b72for Te6edf3i Tff7b72in Tffa657rangeTb4b4b4(T79c0ff1Tb4b4b4, Te6edf3frame_countTb4b4b4)Tb4b4b4:
Tff7b72for Te6edf3j Tff7b72in Tffa657rangeTb4b4b4(Te6edf3segTff7b72.Td2a8ffchannelsTb4b4b4)Tb4b4b4:
Te6edf3offset Tff7b72= Tb4b4b4(Te6edf3i Tff7b72* Te6edf3segTff7b72.Td2a8ffchannelsTb4b4b4) Tff7b72+ Te6edf3j
Te6edf3last_valTb4b4b4[Te6edf3jTb4b4b4] Tff7b72= Te6edf3last_valTb4b4b4[Te6edf3jTb4b4b4] Tff7b72+ Tb4b4b4(Te6edf3alpha Tff7b72* Tb4b4b4(Te6edf3originalTb4b4b4[Te6edf3offsetTb4b4b4] Tff7b72- Te6edf3last_valTb4b4b4[Te6edf3jTb4b4b4]Tb4b4b4)Tb4b4b4)
Te6edf3filteredArrayTb4b4b4[Te6edf3offsetTb4b4b4] Tff7b72= Tffa657intTb4b4b4(Te6edf3last_valTb4b4b4[Te6edf3jTb4b4b4]Tb4b4b4)
Tff7b72return Te6edf3segTff7b72.Td2a8ff_spawnTb4b4b4(Te6edf3dataTff7b72=Te6edf3filteredArrayTb4b4b4)
Tf0883e@register_pydub_effect
Tff7b72def Td2a8ffhigh_pass_filterTb4b4b4(Te6edf3segTb4b4b4, Te6edf3cutoffTb4b4b4)Tb4b4b4:
T8b949e"""
cutoff - Frequency (in Hz) where lower frequency signal will begin to
be reduced by 6dB per octave (doubling in frequency) below this point
"""
Te6edf3RC Tff7b72= T79c0ff1.0 Tff7b72/ Tb4b4b4(Te6edf3cutoff Tff7b72* T79c0ff2 Tff7b72* Te6edf3mathTff7b72.Td2a8ffpiTb4b4b4)
Te6edf3dt Tff7b72= T79c0ff1.0 Tff7b72/ Te6edf3segTff7b72.Td2a8ffframe_rate
Te6edf3alpha Tff7b72= Te6edf3RC Tff7b72/ Tb4b4b4(Te6edf3RC Tff7b72+ Te6edf3dtTb4b4b4)
Te6edf3minvalTb4b4b4, Te6edf3maxval Tff7b72= Te6edf3get_min_max_valueTb4b4b4(Te6edf3segTff7b72.Td2a8ffsample_width Tff7b72* T79c0ff8Tb4b4b4)
Te6edf3original Tff7b72= Te6edf3segTff7b72.Td2a8ffget_array_of_samplesTb4b4b4(Tb4b4b4)
Te6edf3filteredArray Tff7b72= Te6edf3arrayTff7b72.Td2a8ffarrayTb4b4b4(Te6edf3segTff7b72.Td2a8ffarray_typeTb4b4b4, Te6edf3originalTb4b4b4)
Te6edf3frame_count Tff7b72= Tffa657intTb4b4b4(Te6edf3segTff7b72.Td2a8ffframe_countTb4b4b4(Tb4b4b4)Tb4b4b4)
Te6edf3last_val Tff7b72= Tb4b4b4[T79c0ff0Tb4b4b4] Tff7b72* Te6edf3segTff7b72.Td2a8ffchannels
Tff7b72for Te6edf3i Tff7b72in Tffa657rangeTb4b4b4(Te6edf3segTff7b72.Td2a8ffchannelsTb4b4b4)Tb4b4b4:
Te6edf3last_valTb4b4b4[Te6edf3iTb4b4b4] Tff7b72= Te6edf3filteredArrayTb4b4b4[Te6edf3iTb4b4b4] Tff7b72= Te6edf3originalTb4b4b4[Te6edf3iTb4b4b4]
Tff7b72for Te6edf3i Tff7b72in Tffa657rangeTb4b4b4(T79c0ff1Tb4b4b4, Te6edf3frame_countTb4b4b4)Tb4b4b4:
Tff7b72for Te6edf3j Tff7b72in Tffa657rangeTb4b4b4(Te6edf3segTff7b72.Td2a8ffchannelsTb4b4b4)Tb4b4b4:
Te6edf3offset Tff7b72= Tb4b4b4(Te6edf3i Tff7b72* Te6edf3segTff7b72.Td2a8ffchannelsTb4b4b4) Tff7b72+ Te6edf3j
Te6edf3offset_minus_1 Tff7b72= Tb4b4b4(Tb4b4b4(Te6edf3iTff7b72-T79c0ff1Tb4b4b4) Tff7b72* Te6edf3segTff7b72.Td2a8ffchannelsTb4b4b4) Tff7b72+ Te6edf3j
Te6edf3last_valTb4b4b4[Te6edf3jTb4b4b4] Tff7b72= Te6edf3alpha Tff7b72* Tb4b4b4(Te6edf3last_valTb4b4b4[Te6edf3jTb4b4b4] Tff7b72+ Te6edf3originalTb4b4b4[Te6edf3offsetTb4b4b4] Tff7b72- Te6edf3originalTb4b4b4[Te6edf3offset_minus_1Tb4b4b4]Tb4b4b4)
Te6edf3filteredArrayTb4b4b4[Te6edf3offsetTb4b4b4] Tff7b72= Tffa657intTb4b4b4(Tffa657minTb4b4b4(Tffa657maxTb4b4b4(Te6edf3last_valTb4b4b4[Te6edf3jTb4b4b4]Tb4b4b4, Te6edf3minvalTb4b4b4)Tb4b4b4, Te6edf3maxvalTb4b4b4)Tb4b4b4)
Tff7b72return Te6edf3segTff7b72.Td2a8ff_spawnTb4b4b4(Te6edf3dataTff7b72=Te6edf3filteredArrayTb4b4b4)
Tf0883e@register_pydub_effect
Tff7b72def Td2a8ffpanTb4b4b4(Te6edf3segTb4b4b4, Te6edf3pan_amountTb4b4b4)Tb4b4b4:
T8b949e"""
pan_amount should be between -1.0 (100% left) and +1.0 (100% right)
When pan_amount == 0.0 the left/right balance is not changed.
Panning does not alter the *perceived* loundness, but since loudness
is decreasing on one side, the other side needs to get louder to
compensate. When panned hard left, the left channel will be 3dB louder.
"""
Tff7b72if Tff7b72not Tff7b72-T79c0ff1.0 Tff7b72<Tff7b72= Te6edf3pan_amount Tff7b72<Tff7b72= T79c0ff1.0Tb4b4b4:
Tff7b72raise Tf85149ValueErrorTb4b4b4(Ta5d6ff"Ta5d6ffpan_amount should be between -1.0 (100Tffd700% leTa5d6ffft) and +1.0 (100Tffd700% rTa5d6ffight)Ta5d6ff"Tb4b4b4)
Te6edf3max_boost_db Tff7b72= Te6edf3ratio_to_dbTb4b4b4(T79c0ff2.0Tb4b4b4)
Te6edf3boost_db Tff7b72= Tffa657absTb4b4b4(Te6edf3pan_amountTb4b4b4) Tff7b72* Te6edf3max_boost_db
Te6edf3boost_factor Tff7b72= Te6edf3db_to_floatTb4b4b4(Te6edf3boost_dbTb4b4b4)
Te6edf3reduce_factor Tff7b72= Te6edf3db_to_floatTb4b4b4(Te6edf3max_boost_dbTb4b4b4) Tff7b72- Te6edf3boost_factor
Te6edf3reduce_db Tff7b72= Te6edf3ratio_to_dbTb4b4b4(Te6edf3reduce_factorTb4b4b4)
T8b949e# Cut boost in half (max boost== 3dB) - in reality 2 speakers
T8b949e# do not sum to a full 6 dB.
Te6edf3boost_db Tff7b72= Te6edf3boost_db Tff7b72/ T79c0ff2.0
Tff7b72if Te6edf3pan_amount Tff7b72< T79c0ff0Tb4b4b4:
Tff7b72return Te6edf3segTff7b72.Td2a8ffapply_gain_stereoTb4b4b4(Te6edf3boost_dbTb4b4b4, Te6edf3reduce_dbTb4b4b4)
Tff7b72elseTb4b4b4:
Tff7b72return Te6edf3segTff7b72.Td2a8ffapply_gain_stereoTb4b4b4(Te6edf3reduce_dbTb4b4b4, Te6edf3boost_dbTb4b4b4)
Tf0883e@register_pydub_effect
Tff7b72def Td2a8ffapply_gain_stereoTb4b4b4(Te6edf3segTb4b4b4, Te6edf3left_gainTff7b72=T79c0ff0.0Tb4b4b4, Te6edf3right_gainTff7b72=T79c0ff0.0Tb4b4b4)Tb4b4b4:
T8b949e"""
left_gain - amount of gain to apply to the left channel (in dB)
right_gain - amount of gain to apply to the right channel (in dB)
note: mono audio segments will be converted to stereo
"""
Tff7b72if Te6edf3segTff7b72.Td2a8ffchannels Tff7b72== T79c0ff1Tb4b4b4:
Te6edf3left Tff7b72= Te6edf3right Tff7b72= Te6edf3seg
Tff7b72elif Te6edf3segTff7b72.Td2a8ffchannels Tff7b72== T79c0ff2Tb4b4b4:
Te6edf3leftTb4b4b4, Te6edf3right Tff7b72= Te6edf3segTff7b72.Td2a8ffsplit_to_monoTb4b4b4(Tb4b4b4)
Te6edf3l_mult_factor Tff7b72= Te6edf3db_to_floatTb4b4b4(Te6edf3left_gainTb4b4b4)
Te6edf3r_mult_factor Tff7b72= Te6edf3db_to_floatTb4b4b4(Te6edf3right_gainTb4b4b4)
Te6edf3left_data Tff7b72= Te6edf3audioopTff7b72.Td2a8ffmulTb4b4b4(Te6edf3leftTff7b72.Td2a8ff_dataTb4b4b4, Te6edf3leftTff7b72.Td2a8ffsample_widthTb4b4b4, Te6edf3l_mult_factorTb4b4b4)
Te6edf3left_data Tff7b72= Te6edf3audioopTff7b72.Td2a8fftostereoTb4b4b4(Te6edf3left_dataTb4b4b4, Te6edf3leftTff7b72.Td2a8ffsample_widthTb4b4b4, T79c0ff1Tb4b4b4, T79c0ff0Tb4b4b4)
Te6edf3right_data Tff7b72= Te6edf3audioopTff7b72.Td2a8ffmulTb4b4b4(Te6edf3rightTff7b72.Td2a8ff_dataTb4b4b4, Te6edf3rightTff7b72.Td2a8ffsample_widthTb4b4b4, Te6edf3r_mult_factorTb4b4b4)
Te6edf3right_data Tff7b72= Te6edf3audioopTff7b72.Td2a8fftostereoTb4b4b4(Te6edf3right_dataTb4b4b4, Te6edf3rightTff7b72.Td2a8ffsample_widthTb4b4b4, T79c0ff0Tb4b4b4, T79c0ff1Tb4b4b4)
Te6edf3output Tff7b72= Te6edf3audioopTff7b72.Td2a8ffaddTb4b4b4(Te6edf3left_dataTb4b4b4, Te6edf3right_dataTb4b4b4, Te6edf3segTff7b72.Td2a8ffsample_widthTb4b4b4)
Tff7b72return Te6edf3segTff7b72.Td2a8ff_spawnTb4b4b4(Te6edf3dataTff7b72=Te6edf3outputTb4b4b4,
Te6edf3overridesTff7b72=Tb4b4b4{Ta5d6ff'Ta5d6ffchannelsTa5d6ff'Tb4b4b4: T79c0ff2Tb4b4b4,
Ta5d6ff'Ta5d6ffframe_widthTa5d6ff'Tb4b4b4: T79c0ff2 Tff7b72* Te6edf3segTff7b72.Td2a8ffsample_widthTb4b4b4}Tb4b4b4)
──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────